home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / yase.arc / LINEED.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-12-13  |  7.6 KB  |  220 lines

  1. ******************************************************************
  2. * COPYRIGHT (C) 1986 by Donald Krantz and James Stanley
  3. * - Note: This is a real, live, actual, registered copyright,
  4. *   and should be treated as such. This source code is from
  5. *   the book "68000 Assembly Language", Krantz and Stanley,
  6. *   Addison-Wesley Publishing Company, Reading, MA, 1986.
  7. *   Permission granted by the authors for non-commercial use
  8. *   in programs released to the public domain, as long as this
  9. *   copyright notice remains attached and visible.
  10. *
  11. *****************************************************************
  12. * LINEED - Input line editor. Does editing into a string from
  13. * a CRT device. Supports default value prompting.
  14. *
  15. *    ENTRY:    P0.L is the address of the receiving string
  16. *        P1.W is the screen line number to start editing
  17. *        P2.W is the screen column.
  18. *        P3.W is the max number of screen columns allowed
  19.  
  20. #cursor.h
  21.  
  22.     .xdef    lineed
  23.     .xref    case,cursor,putc,_getkey
  24.  
  25. * The following symbol (and references thereto) required only if
  26. * using the VSCREEN virtual CRT interface.
  27.     .xref    sync_curs    
  28.  
  29. string    equ    8        * Stack frame offsets
  30. line    equ    12        * offset to editing line
  31. column    equ    14        * offset to first editing column
  32. max    equ    16        * offset to max editing cols.
  33.  
  34. *****************************************************************
  35. lineed:
  36.     link    a6,#0        * Establish stack frame
  37.     movem.l    d0-d7/a0-a3,-(a7) * Save caller's registers.
  38.     move.w    max(a6),d7    * get maximum usable column
  39.     add.w    column(a6),d7    * compute max crt column 
  40.     subq.w    #1,d7        * adjust for tests later
  41.     clr.w    D3        * Initialize string index
  42.      move.l    string(a6),a1    * get string base address
  43. loop:
  44.     bsr    update        * update display
  45.     bsr    _getkey        * Get next input key
  46.     move.l    #dispatch,a0    * setup case statement
  47.     bsr    case        * case selector already in D0.
  48.     bra    loop        * end of editing loop.
  49. *****************************************************************
  50. * Branches here when human presses RETURN key.
  51. finis:
  52.     clr.b    0(a1,d3.w)    * Terminate input string w/ null
  53.     addq.l    #4,a7        * Trash last return address
  54.     movem.l    (a7)+,d0-d7/a0-a3 * Restore caller's register
  55.     unlk    a6        * Restore caller's stack frame
  56.     rts
  57. *****************************************************************
  58. * Branches here to display 'old' stuff past cursor.
  59. to_end:
  60.     tst.b    0(a1,d3.w)    * are we pointing at terminal?
  61.     beq    sk1_te        * yes - no action required
  62.     addq.w    #1,d3        * move index up one.
  63.     bra    to_end        * repeat
  64. sk1_te:
  65.     rts
  66. *****************************************************************
  67. * Branches here to return cursor to start of line
  68. to_start:
  69.     clr.w    d3        * Set index to start
  70.     rts
  71. *****************************************************************
  72. * branches here to move the cursor one character to the left. 
  73. left:
  74.     tst.w    d3        * are we at start of line?
  75.     beq    exit_left    * yes, let's blow this popstand
  76.     subq.w    #1,d3        * Index back one character
  77. exit_left:
  78.     rts
  79. ****************************************************************
  80. * Moves the cursor one character to the right.
  81. right:
  82.     tst.b    0(a1,d3.w)    * Is there more stuff to display?
  83.     beq    exit_ri        * Nope, we're done here.
  84.     addq.w    #1,d3        * add one to character index
  85. exit_ri:
  86.     rts
  87. *****************************************************************
  88. * Branch here to delete one character to the right
  89. d_right:
  90.     lea    0(a1,d3.w),a2    * load destination address
  91.     tst.b    (a2)        * check for end of string
  92.     beq    exit_dr        * no need to do anything.
  93.     lea    1(a1,d3.w),a3    * load source address
  94.     move.w    max(a6),D1    * Get max char count
  95.     sub    d3,d1        * Compute transfer count
  96. lp0_dr:
  97.     move.b    (a3)+,(a2)+    * start moving the string in
  98.     dbra    d1,lp0_dr    * do whole string.
  99. exit_dr:
  100.     rts
  101. *****************************************************************
  102. * Branch here to delete one character to the left
  103. d_left:
  104.     tst.w    d3        * Are we at start of string?
  105.     beq    exit_dl        * Yes, no action required.
  106.     bsr    left        * Move cursor one char left
  107.     bra    d_right        * re-use d_right code.
  108. exit_dl:
  109.     rts
  110. *****************************************************************
  111. * Branch here to accept next key typed as a literal
  112. jamload:
  113.     bsr    _getkey        * get next key
  114.     bra    othrs        * shove it in.
  115. *****************************************************************
  116. * Inserts the typed character at the cursor.
  117. others:
  118.     cmp.b    #' ',d0        * Test for valid character
  119.     blt    exit_ot        * No, less than $20, ignore
  120. othrs:
  121.     move.w    max(a6),D1    * Get max char count
  122.     ext.l    d1        * setup for address arithmetic
  123.     lea    -1(a1),a2    * load source address
  124.     add.l    d1,a2        * start at far end of string
  125.     lea    0(a1),a3    * load destination address
  126.     add.l    d1,a3        * start at far end of string
  127.     sub.w    d3,d1        * get transfer count
  128.     bra    sk0_ot        * do dec/tst before first xfer
  129. lp0_ot:
  130.     move.b    -(a2),-(a3)    * start moving the string out
  131. sk0_ot:
  132.     dbra    d1,lp0_ot    * loop over end of string.
  133.     move.w    max(a6),d1    * terminate string, in case of -
  134.     clr.b    (a1,d1.w)    *   overflow into terminal null
  135.     move.b    d0,0(a1,d3.w)    * insert new character
  136.     addq.w    #1,d3        * move string index.
  137. exit_ot:
  138.     rts
  139. *****************************************************************
  140. * prints the character in D0, expanding control chars as req.
  141. c_print:
  142.     move.w    d0,-(a7)    * save character on stack
  143.     cmp.b    #$20,d0        * check if it's a control char
  144.     bge    sk0_cp        * no, just print it.
  145.     move.w    #$005E,-(a7)    * push a circumflex for a prefix
  146.     bsr    putc        * print at cursor.
  147.     addq.l    #2,a7        * restore stack
  148.     add.w    #$0040,(a7)    * make unprintable printable
  149.     addq.w    #1,d1        * increment column
  150. sk0_cp:
  151.     bsr    putc        * put input char, already on stack
  152.     addq.l    #2,a7        * restore stack
  153.     addq.w    #1,d1        * increment column
  154.     rts
  155. *****************************************************************
  156. * Prints the input string and updates cursor
  157. update:
  158.     move.w    line(a6),-(a7)    * set cursor to start of line
  159.     move.w    column(a6),-(a7)  this is X, above is Y
  160.     bsr    cursor        * sets cursor to start
  161.     addq.l    #4,a7        * fix stack
  162.     move.w    column(a6),d1    * d1 will be cursor posit
  163.     clr.w    d4        * d4 will be counter
  164. lp0_sp:
  165.     cmp.w    d4,d3        * are we at cursor?
  166.     bne    sk0_sp        * no, jump
  167.     move.w    d1,d5        * save screen cursor position
  168. sk0_sp:    
  169.     move.b    0(a1,d4.w),d0    * char to print
  170.     beq    sk1_sp        * jump out if it's a null
  171.     bsr    c_print        * output character
  172.     addq.w    #1,d4        * bump character counter
  173.     cmp.w    d1,d7        * test for end of area
  174.     bge    lp0_sp        * repeat if there's room.
  175. sk1_sp:
  176.     cmp    d4,d3        * did we find cursor?
  177.     ble    sk2_sp        * yes, we already found it.
  178.     move.w    d4,d3        * reset string counter
  179.     subq.w    #1,d3        * adjust because d4 incremented
  180.     bra    update        * resync all the pointers
  181. sk2_sp:
  182.     move.b    #' ',d0        * blank rest of edit area
  183.     cmp.w    d1,d7        * did we output enough yet?
  184.     blt    sk3_sp        * jump if we did
  185.     bsr    c_print        * put a blank
  186.     bra    sk2_sp        * try again
  187. sk3_sp:
  188.     move.w    line(a6),-(a7)    * reset cursor
  189.     move.w    d5,-(a7)    * this is cursor position
  190.     bsr    cursor        * now tell the display
  191.     addq.l    #4,a7        * fix stack
  192.     bsr    sync_curs    * only needed if using vscreen
  193.     rts
  194. *****************************************************************
  195. * Input character dispatch table
  196. dispatch:
  197.     dc.w    9        * Case options count
  198.     dc.w    return        * when return => finis
  199.     dc.l    finis
  200.     dc.w    c_w_right    * when c_w_right => to_end
  201.     dc.l    to_end
  202.     dc.w    c_w_left    * when c_w_right => to_start
  203.     dc.l    to_start
  204.     dc.w    c_right        * when c_right => right
  205.     dc.l    right
  206.     dc.w    c_left        * when c_left => left
  207.     dc.l    left
  208.     dc.w    backsp        * when backsp => left
  209.     dc.l    left
  210.     dc.w    left_del    * when left_del => d_left
  211.     dc.l    d_left
  212.     dc.w    right_del    * when right_del => d_right
  213.     dc.l    d_right
  214.     dc.w    lit_prefix    * when lit_prefix => jamload
  215.     dc.l    jamload
  216.     dc.l    others        * default case
  217.  
  218.     end
  219.